home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
gnuish
/
mkinf10
/
pc_term.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-11-01
|
11KB
|
476 lines
/* pc_term.c - BIOS video calls for GNU info
Copyright (C) 1990 Free Software Foundation, Inc.
Thorsten Ohl <td12@ddagsi3.bitnet>, 1990
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Header: e:/gnu/info/RCS/pc_term.c 0.6 90/10/26 20:26:20 tho Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <conio.h>
#include <dos.h>
#include "pc_term.h"
unsigned char term_normal_attrib = NORMAL_ATTRIB;
unsigned char term_inverse_attrib = INVERSE_ATTRIB;
/* Higher level functions. */
void clrscr (void);
void clreop (void);
void clreol (void);
void write_char (int c);
void textattr (unsigned char attrib);
/* Lowest level BIOS calls. */
void set_cursor_position (unsigned char row, unsigned char col);
void scroll_up_active_page (unsigned char lines, unsigned char attrib,
unsigned char top_row, unsigned char left_col,
unsigned char bot_row, unsigned char right_col);
/* supplied by info.c */
extern void clear_eop_slowly (void);
/* Main switch */
void
do_term (int command)
{
if (command < 0400)
/* A character. */
write_char (command);
else
/* Something less trivial. */
switch (command)
{
case terminal_ear_bell:
putchar ('\a');
break;
case terminal_clearEOP:
clreop ();
break;
case terminal_clearEOL:
clreol ();
break;
case terminal_use_begin:
case terminal_use_end:
/* NOP */
break;
case terminal_inverse_begin:
textattr (term_inverse_attrib);
break;
case terminal_end_attributes:
textattr (term_normal_attrib);
break;
default:
clrscr ();
fprintf (stderr, "Internal error: Unknown terminal command.\n");
exit (0);
break;
}
}
#ifdef USE_ASSEMBLER
#define _ax ax
#define _bx bx
#define _cx cx
#define _dx dx
#define _si si
#define _di di
#define _cy
#define _ah ah
#define _al al
#define _bh bh
#define _bl bl
#define _ch ch
#define _cl cl
#define _dh dh
#define _dl dl
#define _es es
#define _cs cs
#define _ss ss
#define _ds ds
/* Careful with semicolons here! */
#define _byte byte ptr
#define _alloc_regs
#define _alloc_regs_x
#define _push(reg) _asm push reg
#define _pop(reg) _asm pop reg
#define _mov(dest,source) _asm mov dest, source
#define _mov_ax(dest,source) _asm mov ax, source _asm mov dest, ax
#define _inc(reg) _asm inc reg
#define _add(reg, n) _asm add reg, n
#define _video(func) _asm mov ah, func _asm int 0x10
#define _video_x _video
#define _keybrd(func) _asm mov ah, func _asm int 0x16
#else /* not USE_ASSEMBLER */
#define _ax _regs.x.ax
#define _bx _regs.x.bx
#define _cx _regs.x.cx
#define _dx _regs.x.dx
#define _si _regs.x.si
#define _di _regs.x.di
#define _cy _regs.x.cflag
#define _ah _regs.h.ah
#define _al _regs.h.al
#define _bh _regs.h.bh
#define _bl _regs.h.bl
#define _ch _regs.h.ch
#define _cl _regs.h.cl
#define _dh _regs.h.dh
#define _dl _regs.h.dl
#define _es _segregs.es
#define _cs _segregs.cs
#define _ss _segregs.ss
#define _ds _segregs.ds
#define _byte (unsigned char)
#define _alloc_regs union REGS _regs
#define _alloc_regs_x union REGS _regs; struct SREGS _segregs
#define _push(reg)
#define _pop(reg)
#define _mov(dest,source) dest = source
#define _mov_ax _mov
#define _inc(reg) (reg)++
#define _add(reg, n) (reg) += n;
#define _video(func) _ah = func; int86 (0x10, &_regs, &_regs)
#define _video_x(func) _ah = func; \
int86x (0x10, &_regs, &_regs, &_segregs)
#define _keybrd(func) _ah = func; int86 (0x16, &_regs, &_regs)
#endif /* not USE_ASSEMBLER */
/* Terminal paramters. */
unsigned char term_attrib = 0x07;
unsigned char term_top_row = 0x00;
unsigned char term_left_col = 0x00;
unsigned char term_bot_row = 0x24;
unsigned char term_right_col = 0x79;
int terminal_rows = 80; /* This should read `cols', Brian... */
int terminal_lines = 25;
#pragma pack(1)
struct video_state_info
{
unsigned int off_static_tab; /* offset of static info table */
unsigned int seg_static_tab; /* segment of static info table */
unsigned char video_mode; /* videomode */
unsigned int num_cols; /* */
unsigned int regen_length; /* */
unsigned int regen_offset; /* */
unsigned int cursor_pos[8]; /* */
unsigned int cursor_mode; /* */
unsigned char active_page; /* */
unsigned int crtc_address; /* */
unsigned char reg_3x8; /* */
unsigned char reg_3x9; /* */
unsigned char num_rows; /* */
unsigned int char_height; /* */
unsigned char act_disp_cc; /* */
unsigned char alt_disp_cc; /* */
unsigned int num_colors; /* */
unsigned char num_pages; /* */
unsigned char scan_lines; /* */
unsigned char prim_char_blk; /* */
unsigned char sec_char_blk; /* */
unsigned char misc_info; /* */
unsigned char reserved_2e_30[3]; /* reserved bytes */
unsigned char avl_memory; /* */
unsigned char save_ptr_state; /* */
unsigned char reserved_33_3f[13]; /* reserved bytes */
};
#pragma pack()
/* Initialize screen output. Currently this just sets the screen
dimensions. */
void
opsys_init_terminal (void)
{
#ifndef USE_ANSI
unsigned int segm;
unsigned int offs;
char check;
struct video_state_info _far *video_state
= (struct video_state_info _far *)
alloca (sizeof (struct video_state_info));
_alloc_regs_x;
if (!video_state)
{
fprintf (stderr, "Stack overflow.\n");
abort ();
}
segm = FP_SEG (video_state);
offs = FP_OFF (video_state);
_mov (_bx, 0x00); /* "implementation type" (???) */
_mov_ax (_es, segm);
_mov (_di, offs);
_video_x (0x1b); /* Return state information function */
_mov (check, _al);
if (check == 0x1b)
{
terminal_lines = video_state->num_rows;
terminal_rows = (int) video_state->num_cols;
}
else
{
#if 0 /* shut up! (on public demand) */
fprintf (stderr, "\aNot a VGA terminal, assuming 80x25 BW.\n");
#endif
term_normal_attrib = FG_BG (WHITE, BLACK);
term_inverse_attrib = FG_BG (BLACK, WHITE);
}
term_attrib = term_normal_attrib;
term_top_row = 0x00;
term_left_col = 0x00;
term_bot_row = (unsigned char) (terminal_lines - 1);
term_right_col = (unsigned char) (terminal_rows - 1);
#endif /* not USE_ANSI */
clrscr ();
}
/* Write the character C, using TERM_ATTRIB as attribute, and step one
column right. */
void
write_char (int c)
{
#ifndef USE_ANSI
_alloc_regs;
_video (0x0f); /* Get active page into _bh. */
_mov (_al, _byte c); /* The character to write. */
_mov (_cx, 0x01); /* Write it once. */
_mov (_bl, term_attrib); /* With current attribute. */
_video (0x09);
_video (0x03); /* Read character position function. */
_inc (_dl); /* increment column */
_video (0x02); /* Set character position function. */
#else /* USE_ANSI */
putchar (c);
#endif /* USE_ANSI */
}
/* Move the cursor to X, Y */
void
opsys_goto_pos (int x, int y)
{
#ifndef USE_ANSI
set_cursor_position ((unsigned char) y, (unsigned char) x);
#else
printf ("\033[%d;%dH", y, x);
#endif
}
/* Clear the screen. */
void
clrscr (void)
{
#ifndef USE_ANSI
scroll_up_active_page (0, term_attrib, term_top_row, term_left_col,
term_bot_row, term_right_col);
#else /* USE_ANSI */
fputs ("\033[2j", stdout);
#endif /* USE_ANSI */
}
/* Clear from the cursor to the end of screen. */
void
clreop (void)
{
#ifndef USE_ANSI
unsigned char row;
_alloc_regs;
_video (0x0f); /* Get active page into _bh */
_video (0x03); /* Read character position function. */
_inc (_dh);
_mov (row, _dh); /* row from which to blank */
clreol ();
scroll_up_active_page (0, term_attrib, row, term_left_col,
term_bot_row, term_right_col);
#else /* USE_ANSI */
clear_eop_slowly ();
#endif /* USE_ANSI */
}
/* Clear from the cursor to the end of the cursor's line. */
void
clreol (void)
{
#ifndef USE_ANSI
int col = 0;
_alloc_regs;
_video (0x0f); /* Get active page into _bh */
_video (0x03); /* Read character position function. */
_mov (col, _dl);
col = term_right_col - col + 1;
_mov (_cx, col);
_mov (_al, ' ');
_mov (_bl, term_attrib);
_video (0x09); /* Write characters at cursor position. */
#else /* USE_ANSI */
fputs ("\033[K", stdout);
#endif /* USE_ANSI */
}
void
set_cursor_position (unsigned char row, unsigned char col)
{
_alloc_regs;
_video (0x0f); /* Get active page into _bh */
_mov (_dh, row);
_mov (_dl, col);
_video (0x02); /* set cursor position function */
}
void
scroll_up_active_page (unsigned char lines, unsigned char attrib,
unsigned char top_row, unsigned char left_col,
unsigned char bot_row, unsigned char right_col)
{
_alloc_regs;
_mov (_al, lines);
_mov (_bh, attrib);
_mov (_cl, left_col);
_mov (_ch, top_row);
_mov (_dl, right_col);
_mov (_dh, bot_row);
_video (0x06);
}
void
textattr (unsigned char attrib)
{
#ifndef USE_ANSI
term_attrib = attrib;
#else /* USE_ANSI */
if (attrib == INVERSE_ATTRIB)
fputs ("\033[7m", stdout);
else
fputs ("\033[0m", stdout);
#endif /* USE_ANSI */
}
/* Get a character. */
int
pc_getc (void)
{
int c = getch ();
if (c != 0x00 && c != 0xE0)
return c;
else
switch (getch ())
{
case 71:
/* Home. */
return 'b';
case 73:
/* Page up. */
case 83:
/* Del. */
return 0177;
case 81:
/* Page down. */
default:
return ' ';
}
}
/*
* Local Variables:
* mode:C
* ChangeLog:ChangeLog
* compile-command:make
* End:
*/